(function() {
    if (typeof d3 === "undefined") {
        console.error("d3 not load");
    }
    var MetroList = function(config) {
        console.log("config", config)
        var me = this;
        me._config = config;
        me._renderTo = config.renderTo; //控件绘制的dom
        me._data = config.data; // 数据
        me._size = config.size; // 绘制几行几列 默认为3 * 3
        me._width = config.width; //  宽度 默认为renderTo的宽度
        me._height = config.height; //高度 默认为renderTo的高
        me._margin = config.margin; // 边距 默认为[146, 30, 126, 30]
        me._layout = config.layout; // ？？似乎没用
        me._drawFunction = config.drawFunction; // 绘制图片的函数，此函数参数 render为绘制dom d为该块的数据
        me._tapFunction = config.tapFunction; // 点击后触发的函数，此函数参数 d为该块数据
         me._ajax = config._ajax;//删除触发函数
        me.handleConfig();
        me.init();
       
    };
    MetroList.prototype.handleConfig = function() {
        var me = this, data = me._data;
        var s = me._size || [];
        switch (s.length) {
            case 0:
                s = [3, 3];
                break;
            case 1:
                s = [s[0], s[0]];
                break;
            default:
                s = [s[0], s[1]];
        }
        me._size = s;
        var m = me._margin || [];
        switch (m.length) {
            case 0:
                m = [146, 30, 126, 30];
                break;
            case 1:
                m = [m[0], m[0], m[0], m[0]];
                break;
            case 2:
                m = [m[0], m[1], m[0], m[1]];
                break;
            case 3:
                m = [m[0], m[1], m[2], m[1]];
                break;
            default:
                m = [m[0], m[1], m[2], m[3]];
        }
        me._margin = m;
        var renderTo = me._renderTo;
        me._width = me._width || (renderTo.clientWidth + 0.5) | 0;
        me._height = me._height || (renderTo.clientHeight + 0.5) | 0;
        console.log("height", me.config);
        var df = function(render, d) {
            if (d) {
                d3.select(render).html(d.name).style("background", me.createRandomColor());
            }
        };
        var tf = function(d) {
            if (d) {
                if (d.link) {
                    var href = window.location.href;

                    CMPlugin.go(href.substring(0, href.lastIndexOf("/")) + "/scene_list.html?link=" + d.link);
                }
                //d3.select(render).html(data.list[index].name).style("background", me.createRandomColor());
            }
        };
        me._drawFunction = me._drawFunction || df;
        me._tapFunction = me._tapFunction || tf;
    };

    MetroList.prototype.init = function() {
        var me = this, renderTo = me._renderTo, width = me._width, height = me._height, data = me._data, size = me._size, margin = me._margin;
        var show = data.show;
        var rowLength = (((show.length - 1) / size[1]) | 0) + 1;
        d3.select(renderTo).html("");
        var t = Date.now();
        me._t = t;
        var container = d3.select(renderTo).append("div").classed("container", true).attr("id", "container_" + t);
        container.style("position", "absolute").style("width", (width - margin[1] - margin[3]) + "px").style("height", (height - margin[0] - margin[2]) + "px").style("top", margin[0] + 10 + "px").style("left", margin[1] + "px");
        var scroll = container.append("div").classed("scroll", true);
        scroll.style("position", "absolute").style("width", (width - margin[1] - margin[3]) + "px").style("height", (((height - margin[0] - margin[2]) * rowLength / size[0]) | 0) + "px");
        me._scroll = scroll;
        var i_scroll = new iScroll("container_" + t, {
            vScrollbar: false,
            vScroll: true, hScroll: true,
            onScrollEnd: function() {
                var y = this.y;
                var newY = ((y / height - 0.5) | 0) * height;
                if (y !== newY) {
//                    i_scroll.scrollTo(0, newY, 250);
                }
            }
        });
        me._i_scroll = i_scroll;
        me.drawList(scroll);
    };
    MetroList.prototype.drawList = function(scroll) {
        var me = this, data = me._data, margin = me._margin,
                width = me._width, height = me._height, size = me._size, drawFunction = me._drawFunction;
        var show = data.show;

        var metroWidth = ((width - margin[1] - margin[3]) / size[1] + 0.5) | 0;
        var metroHeight = ((height - margin[0] - margin[2]) / size[0] + 0.5) | 0;
        me._metroWidth = metroWidth;
        me._metroHeight = metroHeight;
        for (var i = 0; i < show.length; i++) {
//            var index = show[i];
            if (data.list[show[i]]) {
                var metroContainer = scroll.append("div").classed("metro_container", true);
                var content = metroContainer.append("div").classed("content", true).style("position", "absolute").style("width", metroWidth + "px").style("height", 60 + "px").style("left", "0px").style("top", "0px");
                metroContainer.style("position", "absolute").style("width", metroWidth + "px").style("height", metroHeight + "px").style("left", "0px").style("top", "0px");
                $(metroContainer.node()).data("x", (i % size[1]) * metroWidth).data("y", ((i / size[1]) | 0) * metroHeight);
                $(metroContainer.node()).data("tmpx", (i % size[1]) * metroWidth).data("tmpy", ((i / size[1]) | 0) * metroHeight);
                $(metroContainer.node()).data("index", i);
                $(metroContainer.node()).data("index2", show[i]);
                $(metroContainer.node()).data("scale", 1);
                $(metroContainer.node()).data("data", data.list[show[i]]);
                drawFunction(content.node(), data.list[show[i]]);
                me.setListener(metroContainer);
            }
        }

        me.transitionTmp();
    };
    MetroList.prototype.setListener = function(metroContainer) {
        var me = this;
        $(metroContainer.node()).hammer()
                .on("click", function(e) {

            if (e.bubbles) {
                console.log("tap2")
                me.metroTap(this, e);
            }

        })
                .on("drag", function(e) {
            me.metroDrag(this, e);
        })
                .on("dragstart", function(e) {
            me.metroDragstart(this, e);
        })
                .on("dragend", function(e) {
            me.metroDragend(this, e);
        })
                .on("hold", function() {
            me.metroEdit(this);
        })
                .on("release", function() {
            me.metroRelease(this);
        });
    };
    MetroList.prototype.metroTap = function(dom, e) {
        var me = this, tapFunction = me._tapFunction, data = me._data;
        if (!$(dom).data("edit")) {
            tapFunction(data.list[$(dom).data("index2")]);
        }
    };
    MetroList.prototype.metroEdit = function(dom) {
        var me = this, renderTo = me._renderTo, i_scroll = me._i_scroll;
        if (!$(dom).data("edit")) {
            $(".metro_container").data("edit", true).data("scale", 0.97);
            d3.selectAll(".metro_container").transition().duration(250).style("-webkit-transform", "scale(0.97)");
            var closeImg = d3.selectAll(".metro_container").append("img").classed("close_image", true).style({
                width: "20px",
                height: "20px"
            });
            closeImg.attr("src", "../login/images/close.png").style("position", "absolute").style("right", "15px");
            $(renderTo).hammer().on("click", function(e) {
                if (e.target.className === "close_image") {
                    me.removeMetro(e.target.parentNode);
                } else if ((e.target.className.indexOf("center") !== -1) || e.target.className === "scroll" || e.target.className === "container") {
                    me.metroRestore();
                }
            });
        }
        $(dom).data("hold", true);
        var trans = $(dom.parentNode).css("-webkit-transform");
        i_scroll.destroy();
        i_scroll = null;
        $(dom.parentNode).css("-webkit-transform", trans);
        d3.select(dom).transition().duration(250).style("-webkit-transform", "scale(1.02)");
    };
    MetroList.prototype.metroRestore = function() {
        $(".metro_container").data("edit", false).data("scale", 1);
        d3.selectAll(".metro_container").transition().duration(250).style("-webkit-transform", "scale(1)");
        $(".close_image").remove();
    };
    MetroList.prototype.metroRelease = function(dom) {
        var me = this, t = me._t, height = me._height;
        if ($(dom).data("hold")) {
            $(dom).data("hold", false);
            var trans = $(dom.parentNode).css("-webkit-transform");
            var y = +trans.substr(21, trans.length - 22);
            var i_scroll = new iScroll("container_" + t, {
                vScrollbar: false,
                onScrollEnd: function() {
                    var y = this.y;
                    var newY = ((y / height - 0.5) | 0) * height;
                    if (y !== newY) {
                    }
                }
            });
            i_scroll.scrollTo(0, y, 0);
            me._i_scroll = i_scroll;
            me.transitionTmp();
        }
    };
    MetroList.prototype.metroDrag = function(dom, e) {
        var me = this, data = me._data, width = me._width, height = me._height,
                metroWidth = me._metroWidth, metroHeight = me._metroHeight, margin = me._margin;
        var rightPos = width - margin[1] - margin[3] - metroWidth, bottomPos = height - margin[0] - margin[2] - metroHeight;
        if ($(dom).data("hold")) {
            var x = Math.min(rightPos, Math.max(0, $(dom).data("x") + e.gesture.deltaX)),
                    y = Math.min(bottomPos, Math.max(0, $(dom).data("y") + e.gesture.deltaY));
            $(dom).css("left", x + "px").css("top", y + "px");
            var posInformation = me.getPosInformation();
            if (typeof me._dragTo === "undefined") {
                me._dragTo = me._dragIndex;
            }
            var p;
            var distance = Math.pow(10, 10);
            for (var i = 0; i < posInformation.length; i++) {
                if (Math.pow((x - posInformation[i].x), 2) + Math.pow((y - posInformation[i].y), 2) < distance) {
                    distance = Math.pow((x - posInformation[i].x), 2) + Math.pow((y - posInformation[i].y), 2);
                    p = posInformation[i];
                }
            }
            if (me._dragTo !== Math.min(p.i, data.show.length - 1)) {
                me._dragTo = Math.min(p.i, data.show.length - 1);
              
            }
              me.adjust();
        }
    };
    MetroList.prototype.adjust = function() {
   
        var me = this, index = me._dragIndex, to = me._dragTo, renderTo = me._renderTo, data = me._data;
        var metros = d3.select(renderTo).selectAll(".metro_container");
        metros.each(function() {
            var th = this;
            var i = $(th).data("index");
            if ((i < index && i < to) || (i > index && i > to)) {
                $(th).data("tmpx", $(th).data("x")).data("tmpy", $(th).data("y"));
            } else if ($(th).data("index") > index && $(th).data("index") <= to) {
                metros.each(function() {
                    if ($(this).data("index") === $(th).data("index") - 1) {
                        $(th).data("tmpx", $(this).data("x")).data("tmpy", $(this).data("y"));
                    }
                });
            } else if (i < index && i >= to) {
                metros.each(function() {
                    if ($(this).data("index") === $(th).data("index") + 1) {
                        $(th).data("tmpx", $(this).data("x")).data("tmpy", $(this).data("y"));
                    }
                });
            } else if (i === index) {
                metros.each(function() {
                    if ($(this).data("index") === to) {
                        $(th).data("tmpx", $(this).data("x")).data("tmpy", $(this).data("y"));
                    }
                });
            }

        });
        me.transitionTmp();
    };
    MetroList.prototype.getPosInformation = function() {
        var me = this, data = me._data, margin = me._margin, metroHeight = me._metroHeight,
                metroWidth = me._metroWidth;
        var show = data.show;
        var inf = [];
        for (var i = 0; i < ((((show.length - 1) / me._size[1]) | 0) + 1) * me._size[1]; i++) {
            var pos = {};
            pos.i = i;
            pos.x = (i % 3) * metroWidth;
            pos.y = ((i / 3) | 0) * metroHeight;
            inf.push(pos);
        }
        return inf;
    };
    MetroList.prototype.metroDragstart = function(dom, e) {
        var me = this;
        if ($(dom).data("hold")) {
            me._dragIndex = $(dom).data("index");
            $(dom).css("z-index", 9);
        }

    };
    MetroList.prototype.metroDragend = function(dom, e) {
        var me = this, renderTo = me._renderTo;
        if ($(dom).data("hold")) {
            var metros = d3.select(renderTo).selectAll(".metro_container");
            var index = me._dragIndex, to = me._dragTo;
            metros.each(function() {
                $(this).data("x", $(this).data("tmpx")).data("y", $(this).data("tmpy"));
                var i = $(this).data("index");
                if ((i < index && i < to) || (i > index && i > to)) {
                    $(this).data("index", i);
                } else if (i < index && i >= to) {
                    $(this).data("index", i + 1);
                } else if (i > index && i <= to) {
                    $(this).data("index", i - 1);
                } else if (i === index) {
                    $(this).data("index", to);
                }
            });
            $(dom).css("z-index", 1);
            me._dragIndex = -1;

        }
    };
    MetroList.prototype.transitionTmp = function() {
        var me = this, renderTo = me._renderTo;
        var metros = d3.select(renderTo).selectAll(".metro_container");
        metros.each(function(d, i) {
            if ($(this).data("index") !== me._dragIndex) {
                d3.select(this).transition().duration(250)
                        .style("left", $(this).data("tmpx") + "px")
                        .style("top", $(this).data("tmpy") + "px")
                        .style("-webkit-transform", "scale(" + $(this).data("scale") + ")");
            }
        });
    };
    MetroList.prototype.createRandomColor = function() {
        return "#" + (function(color) {
            return (color += '0123456789abcdef'[Math.floor(Math.random() * 16)])
                    && (color.length === 6) ? color : arguments.callee(color);
        })("");
    };
    MetroList.prototype.removeMetro = function(dom) {
        var me = this, show = me._data.show, renderTo = me._renderTo;
        var metros = d3.select(renderTo).selectAll(".metro_container");
        metros.each(function() {
            var th = this;

            if ($(th).data("index") > $(dom).data("index")) {
                metros.each(function() {
                    if ($(this).data("index") === $(th).data("index") - 1) {
                        $(th).data("tmpx", $(this).data("x")).data("tmpy", $(this).data("y"));
                    }
                });
            }
        });
        metros.each(function() {
            var th = this;
            if ($(th).data("index") > $(dom).data("index")) {
                $(th).data("index", $(th).data("index") - 1);
            }
        });
        for (var i = 0; i < metros[0].length; i++) {
            $(metros[0][i]).data("x", $(metros[0][i]).data("tmpx")).data("y", $(metros[0][i]).data("tmpy"));
        }

        show.splice(show.indexOf($(dom).data("index2")), 1);
      
    
          me._ajax(($(dom).data("index2")));
        me._data.show = show;
        $(dom).remove();

      
        me.transitionTmp();
    };
    MetroList.prototype.addMetro = function(index) {
        var me = this, renderTo = me._renderTo, data = me._data, size = me._size, margin = me._margin,
                height = me._height, width = me._width, scroll = me._scroll, i_scroll = me._i_scroll,
                metroWidth = me._metroWidth, metroHeight = me._metroHeight, t = me._t, drawFunction = me._drawFunction;
        var show = data.show;
        var Metros = d3.select(renderTo).selectAll(".metro_container");
        var i = Metros[0].length;
        Metros.each(function() {
            console.log("index", $(this).data("index"), $(this).data("index2"));
        });
        show.push(index);
        var rowLength = (((show.length - 1) / size[1]) | 0) + 1;
        scroll.style("position", "absolute").style("width", (width - margin[1] - margin[3]) + "px").style("height", (((height - margin[0] - margin[2]) * rowLength / size[0]) | 0) + "px");
        var trans = $(scroll.node()).css("-webkit-transform");
        i_scroll.destroy();
        i_scroll = null;
        var y = +trans.substr(21, trans.length - 22);
        var i_scroll = new iScroll("container_" + t, {
            vScrollbar: false
        });
        i_scroll.scrollTo(0, y, 0);
        me._i_scroll = i_scroll;
        var metroContainer = scroll.append("div").classed("metro_container", true).style("height","60px");
        var content = metroContainer.append("div").classed("content", true).style("position", "absolute").style("width", metroWidth + "px").style("height", metroHeight + "px").style("left", "0px").style("top", "0px");
        metroContainer.style("position", "absolute").style("width", metroWidth + "px").style("height", metroHeight + "px").style("left", "0px").style("top", "0px");
        $(metroContainer.node()).data("x", (i % size[1]) * metroWidth).data("y", ((i / size[1]) | 0) * metroHeight);
        $(metroContainer.node()).data("tmpx", (i % size[1]) * metroWidth).data("tmpy", ((i / size[1]) | 0) * metroHeight);
        $(metroContainer.node()).data("index", i);
        $(metroContainer.node()).data("index2", index);
        $(metroContainer.node()).data("scale", 1);
        $(metroContainer.node()).data("data", data.list[show[i]]);
        drawFunction(content.node(), data.list[show[i]]);
        me.setListener(metroContainer);
        me.transitionTmp();
    };
    /*
     * 供外部调用的方法
     * 增加或编辑
     */
    MetroList.prototype.addList = function() {
        var me = this, data = me._data, renderTo = me._renderTo;
        var allList = me.getAllList();
        var masks = d3.select(renderTo).selectAll(".add_mask");
        if (!masks.empty()) {
            return;
        }
        var addMask = d3.select(renderTo).append("div").classed("add_mask", true);
        addMask.style("width", "100%").style("height", "100%")
                .style("background-color", "black").style("opacity", 0.5).style("position", "fixed");
        var tip = d3.select(renderTo).append("div").classed("tip", true);
        var titleBar = tip.append("div").classed("title_bar", true).html("设置");
        var completeButton = titleBar.append("div").classed("complete_button", true);
        var transButton = titleBar.append("div").classed("trans_button", true);
        $(transButton.node()).hammer().on("click", function() {
            var b = d3.select(this);
            if (b.classed("selected")) {
                b.classed("selected", false);
                goAdd();
            } else {
                b.classed("selected", true);
                goSort();
            }
        });

        $(completeButton.node()).hammer().on("click", function() {
            addMask.remove();
            tip.remove();
            //  me.draw();
            me.transitionTmp();
        });
        var con = tip.append("div").classed("con", true).attr("id", "con");
        var scrollv = con.append("div").classed("scroll_v", true);
        for (var i = 0; i < allList.length; i++) {
            var all = scrollv.append("div").classed("all_scenes", true).classed("all_scenes_" + i, true).html(allList[i].name);
            console.log("allList[i].name", allList[i].name);
            var switcher = all.append("input").classed("switcher", true);
            if (allList[i].selected) {
                switcher.attr("checked", "checked");
            }
            switcher.attr("type", "checkbox");
            $(switcher.node()).data("other", all).data("index", i);

            var checkbox = $(".all_scenes_" + i + " :checkbox").iphoneStyle({
                checkedLabel: 'YES',
                uncheckedLabel: 'NO',
                onChange: function(e) {
                    allList[e.data("index")].selected = !allList[e.data("index")].selected;
                    if (allList[e.data("index")].selected) {
                        me.addMetro(e.data("index"));
                    } else {
                        var metros = d3.select(renderTo).selectAll(".metro_container");
                        metros.each(function() {
                            if (e.data("index") === $(this).data("index2")) {
                                me.removeMetro(this);
                            }
                        });
                    }
                }
            });
        }

        new iScroll('con', {
            vScrollbar: false
        });
        var sort = tip.append("div").classed("sort", true).attr("id", "sort");
        var sortscroll = sort.append("div").classed("scroll_v", true).style("height", me.getList().length * 52 + "px");
        var i_Scroll = new iScroll('sort', {
            vScrollbar: false
        });
        function goAdd() {
            con.transition().duration(250).style("left", "10%");
            sort.transition().duration(250).style("left", "100%");
        }
        function goSort() {
            con.transition().duration(250).style("left", "-90%");
            sort.transition().duration(250).style("left", "10%");
            var scenes = me.getList();
            sortscroll.html("");
            var p = 0;
            var mi = 0;
            var trans;
            for (var i = 0; i < scenes.length; i++) {
                var sortList = sortscroll.append("div").classed("sort_list", true).classed("list_" + i, true).html(scenes[i].name);
                var dragButton = sortList.append("div").classed("drag_button", true);
                $(dragButton.node()).data("index", i).data("list", sortList).hammer().on("drag", function(e) {
                    var sortList = $(this).data("list");
                    var i = $(this).data("index");
                    var y = e.gesture.deltaY;
                    mi = i;
                    p = ((y / 52) | 0) + i;
                    sortList.style("-webkit-transform", "translate(0px," + y + "px)").style("z-index", 99);
                });
                $(dragButton.node()).hammer().on("dragstart", function() {
                    trans = $(sortscroll.node()).css("-webkit-transform");
                    i_Scroll.destroy();
                    i_Scroll = null;
                    $(sortscroll.node()).css("-webkit-transform", trans);
                });
                $(dragButton.node()).hammer().on("dragend", function() {
                    me.sortList(mi, p);
                    if (!i_Scroll) {
                        i_Scroll = new iScroll('sort', {
                            vScrollbar: false
                        });
//                        var trans =$(sortscroll.node()).css("-webkit-transform");
                        console.log("trans", trans)
                        var tmpy = +trans.substr(21, trans.length - 22);
                        console.log("y", tmpy);
                        i_Scroll.scrollTo(0, tmpy, 0);
                    }
                    goSort();
                });
            }
        }
    };
    MetroList.prototype.getAllList = function() {
        var me = this, data = me._data;
        var list = data.list, show = data.show;
        var al = [];
        for (var i = 0; i < list.length; i++) {
            var flag = false;
            for (var j = 0; j < show.length; j++) {
                if (show[j] === i) {
                    flag = true;
                    break;
                }
            }
            if (flag) {
                list[i].selected = true;
            } else {
                list[i].selected = false;
            }
            al.push(list[i]);
        }
        return al;
    };
    MetroList.prototype.getList = function() {
        var me = this, data = me._data, renderTo = me._renderTo;
        var show = data.show, l = data.list;
        var list = [];
        //var sort = [];
        var metros = d3.select(renderTo).selectAll(".metro_container");
        metros.each(function(d, i) {
            list[$(this).data("index")] = l[show[i]];
        });
        me._list = list;
        return list;
    };
    MetroList.prototype.sortList = function(index, to) {
        var me = this, renderTo = me._renderTo;
        var metros = d3.select(renderTo).selectAll(".metro_container");
        metros.each(function() {
            var th = this;
            var i = $(th).data("index");
            if ((i < index && i < to) || (i > index && i > to)) {
                $(th).data("tmpx", $(th).data("x")).data("tmpy", $(th).data("y"));
            } else if ($(th).data("index") > index && $(th).data("index") <= to) {
                metros.each(function() {
                    if ($(this).data("index") === $(th).data("index") - 1) {
                        $(th).data("tmpx", $(this).data("x")).data("tmpy", $(this).data("y"));
                    }
                });
            } else if (i < index && i >= to) {
                metros.each(function() {
                    if ($(this).data("index") === $(th).data("index") + 1) {
                        $(th).data("tmpx", $(this).data("x")).data("tmpy", $(this).data("y"));
                    }
                });
            } else if (i === index) {
                metros.each(function() {
                    if ($(this).data("index") === to) {
                        $(th).data("tmpx", $(this).data("x")).data("tmpy", $(this).data("y"));
                    }
                });
            }

        });
        metros.each(function() {
            $(this).data("x", $(this).data("tmpx")).data("y", $(this).data("tmpy"));
            var i = $(this).data("index");
            if ((i < index && i < to) || (i > index && i > to)) {
                $(this).data("index", i);
            } else if (i < index && i >= to) {
                $(this).data("index", i + 1);
            } else if (i > index && i <= to) {
                $(this).data("index", i - 1);
            } else if (i === index) {
                $(this).data("index", to);
            }
        });
        //me.transitionTmp();
    };
    if (typeof Clickmed === "undefined") {
        Clickmed = {};
    }
    Clickmed.MetroList = MetroList;
})();